#!/usr/bin/env python
# Andern
# A python ID3v2 tagging application
#################################################################################
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
##################################################################################
#05.03.2008

import pygtk; pygtk.require("2.0")
import gtk
import pyid3lib
import os
import optparse
import linecache

optparser = optparse.OptionParser()
optparser.add_option("-l", "--local", help="runs the app in local mode", dest="is_local", action="store_true", default="no")
(options, args) = optparser.parse_args()

# More nasty hackage	
if (options.is_local == True):
	version = "SVN-REV-%s" % linecache.getline('.svn/entries', 4)
else:
	version = "SVN-REV-%s" % linecache.getline('/usr/bin/andern-rev/entries', 4)

# start our class
class andernmain:

	# You have no idea...
	genres = ['Blues', 'Classic Rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', 'Hip-Hop', 'Jazz', 'Metal', 'New Age', 'Oldies', 'Other', 'Pop', 'R&B', 'Rap', 'Reggae', 'Rock', 'Techno', 'Industrial', 'Alternative', 'Ska', 'Death Metal', 'Pranks', 'Soundtrack', 'Euro-Techno', 'Ambient', 'Trip-Hop', 'Vocal', 'Jazz/Funk', 'Fusion', 'Trance', 'Classical', 'Instrumental', 'Acid', 'House', 'Game', 'Sound Clip', 'Gospel', 'Noise', 'Alternative Rock', 'Bass', 'Soul', 'Punk', 'Space', 'Meditative', 'Instrumental Pop', 'Instrumental Rock', 'Ethnic', 'Gothic', 'Darkwave', 'Techno-Industrial', 'Electronic', 'Pop-Folk', 'Eurodance', 'Dream', 'Southern Rock', 'Comedy', 'Cult', 'Gangsta', 'Top 40', 'Christian Rap', 'Pop/Funk', 'Jungle', 'Native American', 'Cabaret', 'New Wave', 'Psychadelic', 'Rave', 'Showtunes', 'Trailer', 'Lo-Fi', 'Tribal', 'Acid Punk', 'Acid Jazz', 'Polka', 'Retro', 'Musical', 'Rock & Roll', 'Hard Rock']
	
	fileopen = gtk.FileChooserDialog("Choose File", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
	fileopen.set_default_response(gtk.RESPONSE_OK)
	fileopen.set_current_folder(os.path.expanduser("~"))
	
	def destroy(self, *args):
		print "destroy signal occured"
		gtk.main_quit()
		
	def OpenFile(self, *args):
		a = ["","",""]
		# We need to clear the boxes
		self.artistbox.set_text("")
		self.titlebox.set_text("")
		self.albumbox.set_text("")
		self.trackbox.set_text("")
		self.fileopen.run()
		print self.fileopen.get_filename(), 'selected'
		self.fileopen.hide()
		self.x = pyid3lib.tag( self.fileopen.get_filename() )
		
		try:
			self.ourGenre = self.x[self.x.index('TCON')]['text'] # In ID3, TCON holds the genre number
			self.ourGenre2 = self.ourGenre.strip('()')
			print 'we found genre number ' + self.ourGenre + ' which propogates to ' + self.genres[int(self.ourGenre.strip('()'))] # For genre testing
		except:
			print "No genre found"
		try:
			self.artistbox.set_text(self.x.artist)
		except:
			self.x.artist = ""
			print "Missing Artist for %s" % self.fileopen.get_filename() 
		try:
			self.titlebox.set_text(self.x.title)
		except:
			self.x.title = ""
			print "Missing Title for %s" % self.fileopen.get_filename() 
		try:
			self.albumbox.set_text(self.x.album)
		except:
			self.x.album = ""
			print "Missing Album for %s" % self.fileopen.get_filename() 
		try:
			self.trackbox.set_text(self.x[self.x.index('TRCK')]['text']) # im not exactly sure why self.x.track doesnt work here, but it just doesnt...
		except:
			print "Missing Track for %s" % self.fileopen.get_filename()
		try:
			self.genrebox.set_active(int(self.ourGenre2))
		except:
			print "Missing Genre for %s" % self.fileopen.get_filename() # this is not to be confused with the above "No Genre Found", this is for when its completely NULL on the tag
		# If we succesfully get through everything, just spit out this message
		self.sbar.addItem("Successfully opened %s" % self.fileopen.get_filename().rpartition('/')[2]) #sorry windows :P
		#self.statuslabel.set_markup("<b>Sucessfully opened</b>")

		
	def SaveID3(self, *args):
		self.x.artist = self.artistbox.get_text()
		self.x.title = self.titlebox.get_text()
		self.x.album = self.albumbox.get_text()
		#self.x.track = self.trackbox.get_text()
		
		# this is gonna be a mess...
		
		# set track
		ourTrack = self.trackbox.get_text()
		self.x.track = ourTrack
		
		#f = self.x.index('TRCK')
		#g = self.x[f]
		#g["text"] = int(self.trackbox.get_text())
		#self.x[f] = g
		
		# set genres
		try:
			active = self.genrebox.get_active()
			i = self.x.index('TCON')
			d = self.x[i]
			d["text"] = "(" + str(active) + ")"
			self.x[i] = d
			self.x.update()
			print "(" + str(active) + ")"
		except:
			print "MP3 Has No TCON Frame!"
		#self.statuslabel.set_markup("<b>Sucessfully saved</b>")
		self.sbar.addItem("Successfully saved %s" % self.fileopen.get_filename().rpartition('/')[2]) #sorry windows :P

	def AboutDiag(self, *args):
		aboutw = gtk.AboutDialog()
		aboutw.set_name('Andern')
		aboutw.set_copyright('Copyright 2008, GPL2')
		aboutw.set_authors(['Clayton Thompson', '\nWith patches by Kenneth Prugh', '\nLicensed under the GPL-2'])
		
		# woot, cleaned up the nasty hack
		# this is still pretty messy though...
		if (options.is_local == True):
			f = open("COPYING")
			self.gpl2 = f.read()
			f.close
		else:
			try:
				f = open("/usr/bin/COPYING") 
				self.gpl2 = f.read()
				f.close
			except:
				self.gpl2 = "/using/bin/COPYING not found!\nIf you installed using the setup script, please check the permissions on /usr/bin/COPYING\nOr if you are running the script from a downloaded tarball, please run using the -l or --local option"
		aboutw.set_license(self.gpl2)
		aboutw.set_wrap_license(True)
		aboutw.set_version(version)
		aboutw.set_website('http://andern.googlecode.com')
		aboutw.run()
		aboutw.hide()
	
	# heres our initialization
	def __init__(self):
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.set_resizable(False) # Just for the time being until i can rework the table (maybe just drop the tables all together :P)
		self.table = gtk.Table(8, 2, False)
		#self.label = gtk.Label("Andern -- An ID3 Editor")
		self.artistlabel = gtk.Label("artist:")
		self.titlelabel = gtk.Label("title:")
		self.albumlabel = gtk.Label("album:")
		self.tracklabel = gtk.Label("track:")
		self.genrelabel = gtk.Label("genre:")
		
		self.window.set_border_width(5)
		self.window.set_title("Andern " + version)
		
		# this stuff is no longer needed because the new toolbar
		# but keeping... just incase
		#self.openbutton = gtk.Button("Open MP3")
		#self.openbutton.connect("clicked", self.OpenFile, None)
		#self.aboutbutton = gtk.Button("About")
		#self.aboutbutton.connect("clicked", self.AboutDiag, None)
		#self.savebutton = gtk.Button("Save")
		#self.savebutton.connect("clicked", self.SaveID3, None)
		#self.closebutton = gtk.Button("Close")
		#self.closebutton.connect("clicked", self.destroy, None)
		self.artistbox = gtk.Entry()
		self.titlebox = gtk.Entry()
		self.albumbox = gtk.Entry()
		self.trackbox = gtk.Entry()
		#self.statuslabel = gtk.Label("Idle")
		#self.statuslabel.set_justify(gtk.JUSTIFY_CENTER)
		self.seperator1 = gtk.HSeparator()
		self.seperator2 = gtk.HSeparator()
		
		# Here comes the toolbar!
		openicon = gtk.Image()
		openicon.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_SMALL_TOOLBAR)
		saveicon = gtk.Image()
		saveicon.set_from_stock(gtk.STOCK_SAVE, gtk.ICON_SIZE_SMALL_TOOLBAR)
		closeicon = gtk.Image()
		closeicon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
		abouticon = gtk.Image()
		abouticon.set_from_stock(gtk.STOCK_ABOUT, gtk.ICON_SIZE_SMALL_TOOLBAR)
		self.toolbar =  gtk.Toolbar()
		self.toolbar.set_style(gtk.TOOLBAR_BOTH)
		self.open_button = self.toolbar.append_item(
			"Open MP3",
			"Opens an MP3 file to edit",
			"eh?",
			openicon,
			self.OpenFile)
		self.save_button = self.toolbar.append_item(
			"Save MP3",
			"Saves an MP3 file's ID3 tag",
			"eh?",
			saveicon,
			self.SaveID3)
		self.toolbar.append_space()
		self.about_button = self.toolbar.append_item(
			"About",
			"About Andern",
			"eh?", #ugh
			abouticon,
			self.AboutDiag)
		self.close_button = self.toolbar.append_item(
			"Close",
			"Closes Andern",
			"eh?", #ok gtk2, wtf is this!?!??
			closeicon,
			self.destroy)

		# Setup our genre combobox!
		self.genrebox = gtk.combo_box_new_text()
		self.genrebox.set_wrap_width(5)
		for i in range(0, 79):
			self.genrebox.insert_text(i, self.genres[i])
		
		#setup statusbar
		self.stbar = gtk.Statusbar()
		self.sbar = statusBar(self.stbar)
		
		# we have to pack the table
		self.table.attach(self.toolbar, 0, 2, 0, 1)
		self.table.set_row_spacing(0, 12)
		self.table.attach(self.artistlabel, 0, 1, 1, 2)
		self.table.attach(self.titlelabel, 0, 1, 2, 3)
		self.table.attach(self.albumlabel, 0, 1, 3, 4)
		self.table.attach(self.tracklabel, 0, 1, 4, 5)
		self.table.attach(self.genrelabel, 0, 1, 5, 6)
		#self.table.attach(self.artistlabel, 0, 1, 3, 4)
		#self.table.attach(self.titlelabel, 0, 1, 4, 5)
		#self.table.attach(self.albumlabel, 0, 1, 5, 6)
		self.table.attach(self.artistbox, 1, 2, 1, 2, xpadding=15)
		self.table.attach(self.titlebox, 1, 2, 2, 3, xpadding=15)
		self.table.attach(self.albumbox, 1, 2, 3, 4, xpadding=15)
		self.table.attach(self.trackbox, 1, 2, 4, 5, xpadding=15)
		self.table.attach(self.genrebox, 1, 2, 5, 6, xpadding=15)
		#self.table.attach(self.closebutton, 1, 2, 6, 7)
		#self.table.attach(self.aboutbutton, 0, 1, 6, 7)
		self.table.set_row_spacing(5, 12)
		self.table.set_row_spacing(6, 12)
		self.table.attach(self.seperator2, 0, 2, 6, 7)
		self.table.attach(self.stbar, 0, 2, 7, 8, xpadding=15)
		
		# not sure what this does :S		
		self.window.add(self.table)
		#self.openbutton.show()
		#self.closebutton.show()
		#self.aboutbutton.show()
		#self.savebutton.show()
		#self.artistbox.show()
		#self.titlebox.show()
		#self.albumbox.show()
		#self.artistlabel.show()
		#self.titlelabel.show()
		#self.albumlabel.show()
		#self.tracklabel.show()
		self.window.show_all() #Doesn't actually work otherwise
		##self.label.show()
		#self.table.show()
		#self.stbar.show()
		#self.seperator1.show()
		#self.seperator2.show()
		#self.toolbar.show()
		
	def main(self):
		gtk.main()

class statusBar:
	"""Manage statusbar """
	def __init__(self, sbar):
		""" Initialize statusbar to default values and remove size grip """
		self.sbar = sbar
		self.smsg = self.sbar.get_context_id("standard message")
		self.sbar.set_has_resize_grip(False)
		self.sbar.push(self.smsg, "Idle")

	def addItem(self, item, *args):
		""" Add item to statusbar and pop old item """
		self.popItem()
		self.sbar.push(self.smsg, item)

	def popItem(self):
		""" Pop current item """
		self.sbar.pop(self.smsg)
		
if __name__ == "__main__":

	andern = andernmain()
	andern.main()
